using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Web;
using System.Web.UI;
using Soveryn.Commerce.API;
using Soveryn.Commerce.Shared;

/// <summary>
/// The basic base class for most pages in the client website. This handles most authentication and initializes page data, as well as provide some helper functions.  It also defines the SEO parameters for the page which are used by the MasterPageBaseClass.
/// </summary>

namespace Soveryn.Commerce.BaseClasses
{

    public class PageBaseClass : System.Web.UI.Page
    {

        //information from the app settings
        public static String WebsiteAPIKey = ConfigurationManager.AppSettings["WebsiteAPIKey"];
        public static String WebsiteAPIURL = ConfigurationManager.AppSettings["WebsiteAPIURL"];
        public static String CustomerAPIURL = ConfigurationManager.AppSettings["CustomerAPIURL"];
        public static String EmployeeAPIURL = ConfigurationManager.AppSettings["EmployeeAPIURL"];
        public static String EmarketingAPIURL = ConfigurationManager.AppSettings["EmarketingAPIURL"];
        public static String WebsiteToken = WebsiteAPIKey.Substring(0, 8);

        //reference to the parent masterpage
        public MasterPageBaseClass ParentMasterPage;

        //instantiate empty public Item and SKU Properties and data
        public int ItemID = 0;
        public ItemProperties Item;
        public DataSet ItemDataSet;
        public DataTable ItemDataTable;
        public DataTable ItemSKUDataTable;
        public DataTable ItemSKUPropertyNamesDataTable;
        public DataTable ItemSKUPropertyValuesDataTable;
        public DataTable ItemsRelatedDataTable;
        public DataTable SKUsRelatedDataTable;
        public DataTable ItemImages;
        public bool isItemPage = false;

        //website and client
        public WebsiteProperties Website;
        public ClientProperties Client;

        //customer data
        public CustomerProperties Customer;
        public string CustomerCartSessionID = "";
        public bool isLoggedIn = false;
        
        //page data
        public int PageID = 0;
        public PageProperties Properties;
        public DataSet PageDataSet;
        public DataTable PageDataTable;
        public DataTable PageDoodadsInstanceListTable;
        public bool checkTitleForRedirect = true;

        //employee fields
        public string EmployeeToken;
        public Boolean EditMode = false;
        public Boolean EmployeeLoggedIn = false;

        protected void Page_PreInit(object sender, EventArgs e)
        {

            //retrieve website details
            Website = WebsiteData.WebsiteDetail();

            //get employee token if present and set to cookie
            if (!String.IsNullOrEmpty(Request.QueryString["EmployeeToken"]))
            {
                Response.Cookies.Add(new HttpCookie("EmployeeToken", Request.QueryString["EmployeeToken"]));
                EmployeeToken = Request.QueryString["EmployeeToken"];
            }

            if (Request.Cookies["EmployeeToken"] != null && String.IsNullOrEmpty(EmployeeToken))
                EmployeeToken = Request.Cookies["EmployeeToken"].Value;

            //log in employee
            bool wasDebug = Website.IsDebugMode.Value;
            Website.IsDebugMode = false;
            if (!String.IsNullOrEmpty(EmployeeToken))
                if (EmployeeToken != "false")
                {

                    Dictionary<string, object> EmployeeExternalSessionValidArgs = new Dictionary<string, object>();
                    EmployeeExternalSessionValidArgs.Add("EmployeeExternalSessionID", EmployeeToken);
                    EmployeeExternalSessionValidArgs.Add("WebsiteAPIKey", WebsiteAPIKey);
                    APIEnvelope env = Soveryn.Commerce.Shared.API.Call(PageBaseClass.EmployeeAPIURL, "EmployeeExternalSessionValid", EmployeeExternalSessionValidArgs, false, false);
                    if ((bool)env.response)
                    {
                        SwitchToSecureIfSSLInstalled();
                        EmployeeLoggedIn = true;
                        EditMode = true;

                        if (wasDebug)
                            Website.IsDebugMode = true;

                        if (Request.Cookies["EditMode"] != null)
                            if (Request.Cookies["EditMode"].Value == "false")
                                EditMode = false;

                    }
                }

            //website under construction
            if (!Website.WebsiteLive.Value && !EmployeeLoggedIn)
            {
                if (!String.IsNullOrEmpty(Request.QueryString["bypass"]))
                    Response.Cookies["bypass"].Value = "1";
                else if (Request.Cookies["bypass"] == null)
                    Response.Redirect("/UnderConstruction.html", true);
            }

            //get page data
            bool pageIDFromQuery = false;
            if (PageID == 0)
                if (!String.IsNullOrEmpty(Request.QueryString["PageID"]))
                {
                    PageID = Convert.ToInt32(Request.QueryString["PageID"]);
                    pageIDFromQuery = true;
                }
                else if (Page.RouteData.Values["PageID"] != null)
                    PageID = Convert.ToInt32(Page.RouteData.Values["PageID"].ToString());
                else
                    PageID = Website.HomePageID.Value;
            PageDataSet = WebsiteData.PageDetails(PageID);
            if (!DataUtils.HasRecords(PageDataSet, 0))
                ResponseNotFound();

            //get page data
            PageDataTable = PageDataSet.Tables["PageDetails"];
            Properties = PageProperties.Create(PageDataTable.Rows[0]);
            PageID = Properties.PageID.Value;

            if (pageIDFromQuery)
                Response.RedirectPermanent(Properties.SEO.GetURL(Page), true);

            //calculate publish state
            PageProperties.CalculatePublishStatus(ref Properties, Website.TimeZone.Value);
            if ((!Properties.IsPublished && !EmployeeLoggedIn) || String.IsNullOrEmpty(Properties.TemplateLayoutTypeInherited) || Properties.TemplateLayoutTypeInherited == "inherit")
                ResponseForbidden();
            
            //get doodad list for this page
            if (DataUtils.HasRecords(PageDataSet, "DoodadInstanceListForPage"))
                PageDoodadsInstanceListTable = PageDataSet.Tables["DoodadInstanceListForPage"];

            //get item
            bool itemIDFromQuery = false;
            if (!String.IsNullOrEmpty(Request.QueryString["ItemID"]))
            {
                ItemID = Convert.ToInt32(Request.QueryString["ItemID"]);
                ItemDataSet = WebsiteData.ItemDetail(ItemID);
                itemIDFromQuery = true;
            }
            else if (Page.RouteData.Values["ItemID"] != null)
            {
                ItemID = Convert.ToInt32(Page.RouteData.Values["ItemID"].ToString());
                ItemDataSet = WebsiteData.ItemDetail(ItemID);
            }

            //set item data
            if (ItemDataSet != null && DataUtils.HasRecords(ItemDataSet, "ItemDetail"))
            {

                isItemPage = true;

                ItemDataTable = ItemDataSet.Tables["ItemDetail"];

                if (DataUtils.HasRecords(ItemDataSet, "ItemSKU"))
                    ItemSKUDataTable = ItemDataSet.Tables["ItemSKU"];
                if (DataUtils.HasRecords(ItemDataSet, "PropertyNameTable"))
                    ItemSKUPropertyNamesDataTable = ItemDataSet.Tables["PropertyNameTable"];
                if (DataUtils.HasRecords(ItemDataSet, "PropertyValueTable"))
                    ItemSKUPropertyValuesDataTable = ItemDataSet.Tables["PropertyValueTable"];
                if (DataUtils.HasRecords(ItemDataSet, "ItemsRelated"))
                    ItemsRelatedDataTable = ItemDataSet.Tables["ItemsRelated"];
                if (DataUtils.HasRecords(ItemDataSet, "SKUsRelated"))
                    SKUsRelatedDataTable = ItemDataSet.Tables["SKUsRelated"];
                if (DataUtils.HasRecords(ItemDataSet, "ItemImages"))
                    ItemImages = ItemDataSet.Tables["ItemImages"];

                Item = ItemProperties.Create(ItemDataSet);
                Properties.SEO = Item.SEO;

                if (String.IsNullOrEmpty(Item.ItemHeadTitle))
                    Properties.SEO.HeadTitle = Item.ItemName;
                else
                    Properties.SEO.HeadTitle = Item.ItemHeadTitle;

            }

            if (itemIDFromQuery)
                Response.RedirectPermanent(Properties.SEO.GetURL(Page), true);

            //do 301 redirect if page title is incorrect
            if (checkTitleForRedirect && RouteData.Values["Title"] != null)
                if(RouteData.Values["Title"].ToString() != Properties.SEO.FriendlyURL)
                    Response.RedirectPermanent(Properties.SEO.GetURL(Page), true);

            //set design
            this.MasterPageFile = "~/Files/Themes/" + Website.DesignFolder + "/" + Properties.TemplateLayoutTypeInherited + ".master";

            //get masterpage
            ParentMasterPage = (MasterPageBaseClass)this.Page.Master;

            //retrieve customer
            GetCustomer();

        }

        public static bool EmployeeExternalSessionValid(string EmployeeToken)
        {

            Dictionary<string, object> EmployeeExternalSessionValidArgs = new Dictionary<string, object>();
            EmployeeExternalSessionValidArgs.Add("EmployeeExternalSessionID", EmployeeToken);
            EmployeeExternalSessionValidArgs.Add("WebsiteAPIKey", WebsiteAPIKey);
            APIEnvelope env = Soveryn.Commerce.Shared.API.Call(PageBaseClass.EmployeeAPIURL, "EmployeeExternalSessionValid", EmployeeExternalSessionValidArgs, false, false);
            return (bool)env.response;


        }

        public void GetCustomer()
        {

            bool isCustomerCartSessionIDValid = false;
            string myCustomerCartSessionID = "";

            if (Request.Cookies["CustomerCartSessionID"] != null)
            {
                myCustomerCartSessionID = Request.Cookies["CustomerCartSessionID"].Value;
                isCustomerCartSessionIDValid = true;
            }

            if (isCustomerCartSessionIDValid == false)
            {
                myCustomerCartSessionID = Guid.NewGuid().ToString();
                HttpCookie CartCookie = new HttpCookie("CustomerCartSessionID");
                CartCookie.Value = myCustomerCartSessionID;
                CartCookie.Expires = DateTime.Now.AddMonths(1);
                Response.Cookies.Add(CartCookie);
            }

            CustomerCartSessionID = myCustomerCartSessionID;

            DataSet customerDS = null;
            Dictionary<string, object> args = new Dictionary<string, object>();
            args.Add("WebsiteAPIKey", PageBaseClass.WebsiteAPIKey);
            args.Add("CustomerCartSessionID", CustomerCartSessionID);
            APIEnvelope env = Soveryn.Commerce.Shared.API.Call(PageBaseClass.CustomerAPIURL, "CustomerDetailWebAuth", args, false, false);
            if (env.response != null)
            {
                string response = (string)env.response;
                customerDS = new DataSet();
                customerDS.ReadXml(new StringReader((string)env.response));
            }

            if (DataUtils.HasRecords(customerDS, 0))
            {

                isLoggedIn = true;
                Customer = CustomerProperties.Create(customerDS);

                if (DataUtils.HasRecords(customerDS, 1) && !String.IsNullOrEmpty(Customer.BillingAddressID))
                    Customer.BillingAddress = AddressProperties.Create(customerDS.Tables[1].Rows[0]);

                if (Customer.BillingAddressID == Customer.ShippingAddressID)
                    Customer.ShippingAddress = Customer.BillingAddress;
                else if (DataUtils.HasRecords(customerDS, 2) && !String.IsNullOrEmpty(Customer.ShippingAddressID))
                    Customer.ShippingAddress = AddressProperties.Create(customerDS.Tables[2].Rows[0]);

            }

        }

        public void ExecuteScript(String scriptWithNoTags)
        {

            ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(), scriptWithNoTags, true);

        }

        public void SetEditMode(bool trueorfalse)
        {

            if (trueorfalse)
                Response.Cookies.Add(new HttpCookie("EditMode", "true"));
            else
                Response.Cookies.Add(new HttpCookie("EditMode", "false"));

        }

        public void NavigateTo(String url)
        {

            Response.Redirect(url, true);

        }


        public void Reload()
        {

            Response.Redirect(Request.RawUrl, true);

        }

        public void SwitchToSecureIfSSLInstalled()
        {
            if (Website.IsSSLInstalled == true)
            {
                if (ConfigurationManager.AppSettings["ServerFarmHTTPSSwitching"] == "on")
                {
                    if (Request.ServerVariables.Get("HTTP_CLUSTER-HTTPS") != "on")
                        Response.Redirect(Request.Url.AbsoluteUri.Replace("http://", "https://"), true);
                }
                else
                {
                    if (!Request.IsSecureConnection)
                        Response.Redirect(Request.Url.AbsoluteUri.Replace("http://", "https://"), true);
                }
            }
        }

        public void ResponseForbidden()
        {

            Response.Status = "403 Forbidden";
            Response.StatusCode = 403;
            Response.End();

        }

        public void ResponseNotFound()
        {

            Response.Status = "404 Not Found";
            Response.StatusCode = 404;
            Response.End();

        }

    }

}